home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume5 / pd-last < prev    next >
Encoding:
Text File  |  1989-02-03  |  6.1 KB  |  239 lines

  1. Path: xanth!mcnc!rutgers!ukma!cwjcc!hal!ncoast!allbery
  2. From: ckern@killer.Dallas.TX.US (Chris Kern)
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i062: another "last" -- this one is PD
  5. Message-ID: <8811202058.AA00164@ncoast.UUCP>
  6. Date: 26 Nov 88 23:23:51 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: ckern@killer.Dallas.TX.US (Chris Kern)
  9. Lines: 227
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 5, Issue 62
  13. Submitted-by: "Chris Kern" <ckern@killer.Dallas.TX.US>
  14. Archive-name: pd-last
  15.  
  16. I don't like to complain about any source offering, and certainly
  17. the copyright holder of any code has a right to impose
  18. limitations on its use, but I thought Harvey Moran's restrictions
  19. on his Berkeley `last' look-alike were excessively severe.  Taken
  20. at face value, they would prevent an administrator of several
  21. systems from installing an executable on each system and
  22. archiving the source on only one machine.  ("The source code in
  23. machine readable format [must be] included with any binary
  24. distribution.")
  25.  
  26. Anyway, at the risk initiating "source wars" (hmmm, better
  27. perhaps than "flame wars"), I'm enclosing a version of last.c
  28. that I wrote a couple of years ago for our System V machines.  Its
  29. output is slightly different from Harvey's, and it is even less
  30. Berkeley compatible (although, if someone insists on "still
  31. logged in" as an alternative to not showing the logout time, the
  32. change would be easy to make), but it is not encumbered with
  33. restrictions of any kind.  I have placed the code in the public
  34. domain.
  35.  
  36. Any replies should be directed to my account ckern@killer, since
  37. voa3 is not currently on the net.
  38.  
  39. Cheers,
  40.  
  41. Chris Kern
  42.  
  43.  
  44. #!/bin/sh
  45. # This is a shell archive.  Remove anything before this line,
  46. # then unpack it by saving it in a file and typing "sh file".
  47. #
  48. # Wrapped by ck on Sun Nov 20 14:54:34 EST 1988
  49. # Contents:  last.c last.1
  50.  
  51. echo x - last.c
  52. sed 's/^XX//' > "last.c" <<'@//E*O*F last.c//'
  53. XX#include <stdio.h>
  54. XX#include <sys/types.h>
  55. XX#include <string.h>
  56. XX#include <time.h>
  57. XX#include <utmp.h>
  58.  
  59.  
  60. XX#define     OWTMP_FILE        "/usr/adm/acct/nite/owtmp"        /* file to search after /etc/wtmp */
  61.  
  62. XXstatic char *prog;
  63. XXstatic char *wtmpfile[] = { OWTMP_FILE, WTMP_FILE, NULL };
  64.  
  65. XXstruct list {
  66. XX        struct utmp rec;
  67. XX        struct list *next;
  68. XX        struct list *previous;
  69. XX};
  70.  
  71.  
  72.  
  73. XXmain(argc, argv)            /* last: show recent logins in last-to-first order */
  74. XXint argc;
  75. XXchar *argv[];
  76. XX{
  77. XX    int    i;
  78. XX    void   prproc();
  79. XX    struct list *listp = NULL, *p, *addlist();
  80. XX    struct utmp *entry;
  81. XX    extern void utmpname();
  82. XX    extern struct utmp *getutent();
  83.  
  84. XX    prog = argv[0];
  85.  
  86. XX    for (i = 0; wtmpfile[i] != NULL; i++) {
  87. XX        utmpname(wtmpfile[i]);
  88. XX        while ((entry = getutent()) != NULL)
  89. XX            listp = addlist(listp, entry);
  90. XX    }
  91.  
  92. XX    /* listp points to most recent wtmp entry */
  93.  
  94. XX    for (p = listp; p != NULL; p = p->previous)
  95. XX        if (p->rec.ut_type == USER_PROCESS) {
  96. XX            if (argc == 1)
  97. XX                prproc(p, listp);
  98. XX            else
  99. XX                for (i = 1; i < argc; i++) {
  100. XX                    if (strcmp(p->rec.ut_user, argv[i]) == 0) {
  101. XX                        prproc(p, listp);
  102. XX                        break;
  103. XX                    }
  104. XX                }
  105. XX        }
  106.  
  107. XX    return (0);
  108. XX}
  109.  
  110.  
  111.  
  112. XXstruct list *addlist(head, wtmp)    /* add new wtmp entry to head of list */
  113. XXstruct list *head;
  114. XXstruct utmp *wtmp;
  115. XX{
  116. XX    void     errexit();
  117. XX    register struct list *new;
  118. XX    extern     char *malloc();
  119.  
  120. XX    if ((new = (struct list *) malloc(sizeof(struct list))) == NULL)
  121. XX        errexit("memory error", NULL);
  122. XX    else {
  123. XX        new->rec = *wtmp;
  124. XX        new->next = new;        /* no next yet */
  125. XX        new->previous = head;
  126. XX        if (head != NULL)
  127. XX            head->next = new;
  128. XX    }
  129. XX    return (new);
  130. XX}
  131.  
  132.  
  133.  
  134. XXvoid prproc(start, last)        /* print entries for process */
  135. XXstruct list *start, *last;
  136. XX{
  137. XX    void     prentry();
  138. XX    register struct list *p;
  139.  
  140. XX    prentry(start->rec);
  141. XX    for (p = start->next; p != last; p = p->next)
  142. XX        if (p->rec.ut_pid == start->rec.ut_pid)
  143. XX            prentry(p->rec);
  144. XX    putchar('\n');
  145. XX}
  146.  
  147.  
  148. XX    
  149. XXvoid prentry(wtmp)            /* print wtmp entry */
  150. XXstruct utmp wtmp;
  151. XX{
  152. XX    static char *wkday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  153. XX    static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  154.  
  155. XX    char   line[12 + 1], user[8 + 1];            /* magic numbers courtesy of /usr/include/utmp.h */
  156. XX    struct tm *time;
  157. XX    extern struct tm *localtime();
  158.  
  159. XX    strncpy(line, wtmp.ut_line, 12);
  160. XX    strncpy(user, wtmp.ut_user, 8);
  161. XX    line[12] = user[8] = '\0';
  162. XX    time = localtime(&wtmp.ut_time);
  163. XX    switch (wtmp.ut_type) {
  164. XX    case USER_PROCESS:
  165. XX        printf("%-8s %-12s %s %s %2d %02d:%02d",
  166. XX            user, line, wkday[time->tm_wday], month[time->tm_mon], time->tm_mday, time->tm_hour, time->tm_min);
  167. XX        break;
  168. XX    case DEAD_PROCESS:
  169. XX        printf("  -  %02d:%02d %s", time->tm_hour, time->tm_min, wkday[time->tm_wday]);
  170. XX        break;
  171. XX    default:
  172. XX        sprintf(line, "%d", wtmp.ut_type);
  173. XX        errexit("illegal wtmp.ut_type entry:", line);
  174. XX    }
  175. XX}
  176.  
  177.  
  178.  
  179. XXvoid errexit(s1, s2)            /* print error message and die */
  180. XXchar s1[], s2[];
  181. XX{
  182. XX    extern void exit();
  183.  
  184. XX    fprintf(stderr, s2 == NULL ? "%s: %s\n" : "%s: %s %s\n", prog, s1, s2);
  185. XX    exit(-1);
  186. XX}
  187. @//E*O*F last.c//
  188. chmod u=rw,g=r,o=r last.c
  189.  
  190. echo x - last.1
  191. sed 's/^XX//' > "last.1" <<'@//E*O*F last.1//'
  192. XX.TH LAST 1 VOA
  193. XX.SH NAME
  194. XXlast  \-  show recent logins in last-to-first order
  195. XX.SH SYNOPSIS
  196. XX.B last
  197. XX[
  198. XXuser ...
  199. XX]
  200. XX.SH DESCRIPTION
  201. XX.I Last
  202. XXdisplays recent login and logout times
  203. XXin last-to-first order.
  204. XXIf invoked with
  205. XX.IR user s,
  206. XXoutput is restricted
  207. XXto the login and logout times
  208. XXof the specified account(s).
  209. XX.SH FILES
  210. XX.TP 30
  211. XX/etc/wtmp
  212. XXcurrent accounting file
  213. XX.TP 30
  214. XX/usr/adm/acct/nite/owtmp
  215. XXprevious day's accounting file
  216. XX.SH BUGS
  217. XXCertain types of system errors
  218. XXwill result in
  219. XX.I last
  220. XXfailing to report
  221. XXa user's logout time.
  222. @//E*O*F last.1//
  223. chmod u=rw,g=r,o=r last.1
  224.  
  225. echo Inspecting for damage in transit...
  226. temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
  227. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  228. cat > $temp <<\!!!
  229.     134    418   2944 last.c
  230.      30     88    522 last.1
  231.     164    506   3466 total
  232. !!!
  233. wc  last.c last.1 | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  234. if test -s $dtemp
  235. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  236. else echo "No problems found."
  237. fi
  238. exit 0
  239.